/**
 * 
 */
package projet_v1.basics;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import projet_v1.Breed;
import projet_v1.Human;
import projet_v1.simulation.Field;
import projet_v1.simulation.Location;

/**
 * Test class of Character abstract class.
 * 
 * @author Antoine Lavail
 * 
 */
public class TestCharacter {

    // Fields for setUp.
    // No instances of character because it's an abstract class.
    private Human human1;

    /**
     * @throws java.lang.Exception
     */
    @Before
    public void setUp() throws Exception {
        human1 = new Human(100);
    }

    /**
     * Test method for
     * {@link projet_v1.Character#Character(int, projet_v1.Breed)}.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCharacterIntBreed() {
        // We use a human instance to verify the integrity of the character
        // constructor.
        Human human = new Human(100);
        assertEquals(100, human.getHealthPoints());
        assertEquals(Breed.HUMAN, human.getBreed());

        // IllegalArgumentException for negative healthPoints
        human = new Human(-50);
    }

    /**
     * Test method for
     * {@link projet_v1.Character#Character(int, projet_v1.Breed, projet_v1.simulation.Field, projet_v1.simulation.Location, int)}
     * .
     */
    @Test(expected = NullPointerException.class)
    public void testCharacterIntBreedFieldLocationInt() {
        // We use a human instance to verify the integrity of the character
        // constructor.
        Location l = new Location(20, 20);
        Human human = new Human(100, new Field(40, 40), l);
        assertEquals(100, human.getHealthPoints());
        assertEquals(Breed.HUMAN, human.getBreed());
        assertEquals(l, human.getLocation());

        // NullPointerException for field Field.
        human = new Human(100, null, l);

        // NullPointerException for field Location.
        human = new Human(100, new Field(40, 40), null);
    }

    /**
     * Test method for {@link projet_v1.Character#setHealthPoints(int)}.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testSetHealthPoints() {
        assertEquals(100, human1.getHealthPoints());
        human1.setHealthPoints(50);
        assertEquals(50, human1.getHealthPoints());

        // IllegalArgumentException for negative healthPoints passed.
        human1.setHealthPoints(-5);
    }

    /**
     * Test method for
     * {@link projet_v1.Character#setLocation(projet_v1.simulation.Location)}.
     */
    @Test(expected = NullPointerException.class)
    public void testSetLocation() {
        Location l = new Location(20, 25);
        human1.setLocation(l);
        assertEquals(l, human1.getLocation());

        // NullPointerException for null value of location passed.
        human1.setLocation(null);
    }

    /**
     * Test method for
     * {@link projet_v1.Character#setLastAttackedBy(projet_v1.Breed)}.
     */
    @Test
    public void testSetLastAttackedBy() {
        human1.setLastAttackedBy(Breed.ZOMBIE);
        assertEquals(Breed.ZOMBIE, human1.getLastAttackedBy());
    }

    /**
     * Test method for {@link projet_v1.Character#isAlive()}.
     */
    @Test
    public void testIsAlive() {
        assertTrue(human1.isAlive());
        human1.setHealthPoints(0);
        assertFalse(human1.isAlive());
    }

    /**
     * Test method for {@link projet_v1.Character#reduceHealthPoints(int)}.
     */
    @Test
    public void testReduceHealthPoints() {
        human1.reduceHealthPoints(50);
        assertEquals(50, human1.getHealthPoints());
        human1.reduceHealthPoints(100);
        assertEquals(0, human1.getHealthPoints());
    }
}
